/**
 * className : WrapperArraySerializer
 * <p>
 * version: 1.0.0
 * <p>
 * Date: 2023/11/8
 */

package com.xuyuan.json.jackson.study;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.type.TypeFactory;

import java.io.IOException;
import java.util.List;

public class WrapperArraysBeanDeSerializer extends StdScalarDeserializer implements ContextualDeserializer {
    Class<?> clazz;
    Class<?> binding;
    JavaType javaType;
    boolean hasArray;

    public WrapperArraysBeanDeSerializer() {
        super(Object.class);
    }

    protected WrapperArraysBeanDeSerializer(Class vc, Class binding, boolean hasArray) {
        super(vc);
        this.clazz = vc;
        this.binding = binding;
        this.hasArray = hasArray;
        TypeFactory typeFactory = TypeFactory.defaultInstance();
        if (!hasArray) {
            javaType = typeFactory.constructCollectionType(List.class, binding);
        } else {
            javaType = typeFactory.constructParametricType(clazz, binding);
        }
    }

    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        if (hasArray) {
            JsonToken currentToken = p.getCurrentToken();
            if (currentToken.name().equals("START_ARRAY")) {
                p.nextToken();
                Object o = p.getCodec().readValue(p, javaType);
                p.nextToken();
                return o;
            } else {
                return null;
            }
        } else {
            return p.getCodec().readValue(p, javaType);
        }

    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        WrapArray ann = property.getAnnotation(WrapArray.class);
        Class clazz = ann.value();
        Class<?> bindings = ann.bindings();
        return new WrapperArraysBeanDeSerializer(clazz, bindings, ann.hasArray());
    }
}
